#include "stdafx.h"
#include "CMyMDSpi.h"
#include "CMyMDApi.h"
#include <string.h>
#include <unistd.h>
#include <iostream>

using namespace std;

//处理异常行情值函数
#define MAX_ACCEPTABLE_PRICE (1.0E+5)
#define DEAL_TOO_MAX( x ) if( ((x)>MAX_ACCEPTABLE_PRICE) || ((x)<(0-MAX_ACCEPTABLE_PRICE)) ) x = 0

CMyMDSpi::CMyMDSpi(CMyMDApi* pApi)
{
	m_pApi = pApi;
}

CMyMDSpi::~CMyMDSpi()
{
}

//前置session创建反馈
void CMyMDSpi::OnFrontConnected()
{
	gettimeofday(&endtime, NULL);
	timegap = (endtime.tv_sec - m_pApi->starttime.tv_sec) * 1000 + (endtime.tv_usec - m_pApi->starttime.tv_usec) / 1000;
	printf("front connected!!\r\n");
	cout << "cost time: " << timegap << " ms" << endl;

	//设置返回标示，唤醒阻塞线程
	m_pApi->serverrt = true;
	m_pApi->cond.notify_all();

}

//断链反馈函数
void CMyMDSpi::OnFrontDisconnected(int nReason)
{
	printf("front netconnect cutdown!! reason=%d\r\n", nReason);

	//设置返回标示，唤醒阻塞线程
	m_pApi->serverrt = true;
	m_pApi->cond.notify_all();

}

//行情推送回调函数
void CMyMDSpi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData)
{
	//对可能存在异常值的列进行处理
	DEAL_TOO_MAX(pDepthMarketData->PreOpenInterest);
	DEAL_TOO_MAX(pDepthMarketData->PreClosePrice);
	DEAL_TOO_MAX(pDepthMarketData->PreSettlementPrice);
	DEAL_TOO_MAX(pDepthMarketData->ClosePrice);
	DEAL_TOO_MAX(pDepthMarketData->SettlementPrice);
	DEAL_TOO_MAX(pDepthMarketData->OpenInterest);
	DEAL_TOO_MAX(pDepthMarketData->LastPrice);
	DEAL_TOO_MAX(pDepthMarketData->UpperLimitPrice);
	DEAL_TOO_MAX(pDepthMarketData->LowerLimitPrice);
	DEAL_TOO_MAX(pDepthMarketData->HighestPrice);
	DEAL_TOO_MAX(pDepthMarketData->LowestPrice);
	DEAL_TOO_MAX(pDepthMarketData->OpenPrice);
	DEAL_TOO_MAX(pDepthMarketData->LowestPrice);
	DEAL_TOO_MAX(pDepthMarketData->Turnover);
	DEAL_TOO_MAX(pDepthMarketData->PreDelta);
	DEAL_TOO_MAX(pDepthMarketData->CurrDelta);
	DEAL_TOO_MAX(pDepthMarketData->BidPrice1);
	DEAL_TOO_MAX(pDepthMarketData->BidVolume1);
	DEAL_TOO_MAX(pDepthMarketData->AskPrice1);
	DEAL_TOO_MAX(pDepthMarketData->AskVolume1);


	//打印行情内容
	cout << pDepthMarketData->TradingDay << ","
	<< pDepthMarketData->ExchangeID << ","
	<< pDepthMarketData->LastPrice << ","
	<< pDepthMarketData->PreSettlementPrice << ","
	<< pDepthMarketData->PreClosePrice << ","
	<< pDepthMarketData->PreOpenInterest << ","
	<< pDepthMarketData->OpenPrice << ","
	<< pDepthMarketData->HighestPrice << ","
	<< pDepthMarketData->LowestPrice << ","
	<< pDepthMarketData->Volume << ","
	<< pDepthMarketData->Turnover << ","
	<< pDepthMarketData->OpenInterest << ","
	<< pDepthMarketData->ClosePrice << ","
	<< pDepthMarketData->SettlementPrice << ","
	<< pDepthMarketData->UpperLimitPrice << ","
	<< pDepthMarketData->LowerLimitPrice << ","
	<< pDepthMarketData->PreDelta << ","
	<< pDepthMarketData->CurrDelta << ","
	<< pDepthMarketData->UpdateTime << ","
	<< pDepthMarketData->UpdateMillisec << ","
	<< pDepthMarketData->BidPrice1 << ","
	<< pDepthMarketData->BidVolume1 << ","
	<< pDepthMarketData->AskPrice1 << ","
	<< pDepthMarketData->AskVolume1 << ","
	<< pDepthMarketData->AveragePrice << ","
	<< pDepthMarketData->ActionDay << ","
	<< pDepthMarketData->InstrumentID << ","
	<< pDepthMarketData->ExchangeInstID << ","
	<< pDepthMarketData->BandingUpperPrice << ","
	<< pDepthMarketData->BandingLowerPrice << "," << endl;

}


//自定义用户登录反馈函数，其中有涉及一对多中继模式报送内容
void CMyMDSpi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
	gettimeofday(&endtime, NULL);
	timegap = (endtime.tv_sec - m_pApi->starttime.tv_sec) * 1000 + (endtime.tv_usec - m_pApi->starttime.tv_usec) / 1000;
	//pReject->m_ReasonText为GB2312字符串 ansUTF8为所求UTF8字符串
	GB2312ToUTF8(pRspInfo->ErrorMsg, sizeof(pRspInfo->ErrorMsg), tmpmsg, sizeof(tmpmsg));
	if (pRspInfo && pRspInfo->ErrorID == 0)
	{
		printf("%s user login success!\r\n", pRspUserLogin->UserID);
		cout << "cost time: " << timegap << " ms" << endl;
		printf("ErrorID=%d  Errormsg=%s\r\n", pRspInfo->ErrorID, tmpmsg);


	}
	else
	{
		printf("ErrorID=%d  Errormsg=%s\r\n", pRspInfo->ErrorID, tmpmsg);
		cout << "cost time: " << timegap << " ms" << endl;
	}
	//设置返回标示，唤醒阻塞线程
	m_pApi->serverrt = true;
	m_pApi->cond.notify_all();
}
